package com.example.fasttalk.client;

import static com.example.fasttalk.Constant.GSON;

import com.example.fasttalk.client.ServerApiEnum;
import java.net.Authenticator;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.function.Consumer;

public class HttpActuatorBuilder {
  public static SetServerUrl builder() {
    return new HttpActuator();
  }

  public static class HttpActuator implements SetServerUrl, SetApi {
    String serverUrl;
    ServerApiEnum api;

    Object body;
    Consumer<HttpResponse<String>> executeCallback;
    Consumer<Exception> executeErrorCallback;

    @Override
    public SetApi serverUrl(String serverUrl) {
      this.serverUrl = serverUrl;
      return this;
    }

    @Override
    public HttpActuator api(ServerApiEnum api) {
      this.api = api;
      return this;
    }

    public HttpActuator body(Object data) {
      this.body = data;
      return this;
    }

    public HttpActuator then(Consumer<HttpResponse<String>> function) {
      this.executeCallback = function;
      return this;
    }

    public HttpActuator cath(Consumer<Exception> function) {
      this.executeErrorCallback = function;
      return this;
    }

    public HttpResponse<String> execute() {
      HttpResponse<String> response = null;
      try {
        HttpClient client = HttpClient.newBuilder()
          .version(HttpClient.Version.HTTP_1_1)
          .followRedirects(HttpClient.Redirect.NORMAL)
          .connectTimeout(Duration.ofSeconds(20))
          .authenticator(Authenticator.getDefault())
          .build();
        HttpRequest.Builder builder = HttpRequest.newBuilder()
          .uri(URI.create(serverUrl + api.getPath()))
          .timeout(Duration.ofMinutes(2))
          .header("Content-Type", "application/json");
        // TODO SundayLi 待后续拓展
        switch (api.getType()) {
          case "POST":
            builder.POST(HttpRequest.BodyPublishers.ofString(GSON.toJson(body)));
            break;
          case "PUT":
            builder.PUT(HttpRequest.BodyPublishers.ofString(GSON.toJson(body)));
            break;
          case "GET":
          default:
            break;
        }
        response = client.send(builder.build(), HttpResponse.BodyHandlers.ofString());
        if (executeCallback != null) executeCallback.accept(response);
      } catch (Exception e) {
        // TODO SundayLi idea 的 logger 有空学下姿势
        if (executeErrorCallback != null) executeErrorCallback.accept(e);
      }
      return response;
    }
  }

  interface SetServerUrl {
    SetApi serverUrl(String serverUrl);
  }

  interface SetApi {
    HttpActuator api(ServerApiEnum api);
  }

}
